MODULE YOS_SURF
 
USE YOS_AGS     , ONLY : TAGS
USE YOS_AGF     , ONLY : TAGF
USE YOS_CST     , ONLY : TCST
USE YOS_DIM     , ONLY : TDIM
USE YOS_EXC     , ONLY : TEXC
USE YOS_FLAKE   , ONLY : TFLAKE
USE YOS_LW      , ONLY : TLW
USE YOS_MLM     , ONLY : TMLM
USE YOS_OCEAN_ML, ONLY : TOCEAN_ML
USE YOS_RAD     , ONLY : TRAD
USE YOS_RDI     , ONLY : TRDI
USE YOS_SOIL    , ONLY : TSOIL
USE YOS_SW      , ONLY : TSW
USE YOS_VEG     , ONLY : TVEG
USE YOS_BVOC    , ONLY : TBVOC
USE YOS_URB     , ONLY : TURB

USE ISO_C_BINDING
USE ABORT_SURF_MOD

! (C) Copyright 2005- ECMWF.
!
! This software is licensed under the terms of the Apache Licence Version 2.0
! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
! In applying this licence, ECMWF does not waive the privileges and immunities
! granted to it by virtue of its status as an intergovernmental organisation
! nor does it submit to any jurisdiction.

IMPLICIT NONE

PRIVATE

PUBLIC :: ALLO_SURF, DEALLO_SURF, GET_SURF

TYPE, PUBLIC :: TSURF
  TYPE(TAGS)      :: YAGS 
  TYPE(TAGF)      :: YAGF 
  TYPE(TCST)      :: YCST
  TYPE(TDIM)      :: YDIM
  TYPE(TEXC)      :: YEXC
  TYPE(TFLAKE)    :: YFLAKE
  TYPE(TLW)       :: YLW
  TYPE(TMLM)      :: YMLM
  TYPE(TOCEAN_ML) :: YOCEAN_ML
  TYPE(TRAD)      :: YRAD
  TYPE(TRDI)      :: YRDI
  TYPE(TSOIL)     :: YSOIL
  TYPE(TSW)       :: YSW
  TYPE(TVEG)      :: YVEG
  TYPE(TBVOC)     :: YBVOC
  TYPE(TURB)      :: YURB
END TYPE TSURF

TYPE :: TLIST
  TYPE(TSURF) :: YSURF
  TYPE(C_PTR) :: CPTR 
  TYPE(TLIST),  POINTER :: NEXT
END TYPE TLIST

TYPE(TLIST), POINTER, SAVE :: LIST => NULL()

CONTAINS

SUBROUTINE ALLO_SURF(YDSURF)
IMPLICIT NONE

TYPE(C_PTR), INTENT(OUT) :: YDSURF

TYPE(TLIST), POINTER :: THIS

ALLOCATE(THIS)
THIS%CPTR = C_LOC(THIS%YSURF)
THIS%NEXT => LIST

LIST => THIS
YDSURF = THIS%CPTR

END SUBROUTINE ALLO_SURF


SUBROUTINE DEALLO_SURF(YDSURF)
IMPLICIT NONE

TYPE(C_PTR), INTENT(INOUT) :: YDSURF

TYPE(TLIST), POINTER :: PREVIOUS, CURRENT

PREVIOUS => NULL()
CURRENT => LIST

DO WHILE (ASSOCIATED(CURRENT))
  IF (C_ASSOCIATED(YDSURF,CURRENT%CPTR)) THEN
    IF (ASSOCIATED(PREVIOUS)) THEN
      PREVIOUS%NEXT => CURRENT%NEXT
    ELSE
      LIST => CURRENT%NEXT
    ENDIF
    DEALLOCATE(CURRENT)
    YDSURF = C_NULL_PTR
    RETURN
  ENDIF
  PREVIOUS => CURRENT
  CURRENT => CURRENT%NEXT
END DO

CALL ABORT_SURF('YOS_SURF:DEALLO_SURF: NOT FOUND')

END SUBROUTINE DEALLO_SURF


FUNCTION GET_SURF(YDSURF)
IMPLICIT NONE

TYPE(TSURF), POINTER    :: GET_SURF
TYPE(C_PTR), INTENT(IN) :: YDSURF

TYPE(TLIST), POINTER :: CURRENT

CURRENT => LIST

DO WHILE (ASSOCIATED(CURRENT))
  IF (C_ASSOCIATED(YDSURF,CURRENT%CPTR)) THEN
    GET_SURF => CURRENT%YSURF
    RETURN
  ENDIF
  CURRENT => CURRENT%NEXT
END DO

CALL ABORT_SURF('YOS_SURF:GET_SURF: NOT FOUND')

END FUNCTION GET_SURF

END MODULE YOS_SURF

